package cn.jasonone.tio.tcp.model;

import cn.jasonone.tio.tcp.commons.Command;
import cn.jasonone.tio.tcp.config.constants.CharsetEnum;
import lombok.Data;
import lombok.experimental.Accessors;

import java.nio.charset.Charset;

/**
 * 消息头定义: <br>
 *
 * <table border=1>
 *     <tr>
 *         <td>业务ID</td>
 *         <td>字符编码</td>
 *         <td>消息是否加密</td>
 *         <td>指令类型</td>
 *         <td>指令分组</td>
 *         <td>指令编码</td>
 *         <td>消息签名</td>
 *         <td>消息体长度</td>
 *     </tr>
 *     <tr>
 *         <td> 32 Byte </td>
 *         <td> 1 Byte </td>
 *         <td> 1 Byte </td>
 *         <td> 1 Byte </td>
 *         <td> 4 Byte </td>
 *         <td> 4 Byte </td>
 *         <td> 32 Byte </td>
 *         <td> 4 Byte </td>
 *     </tr>
 * </table>
 *
 * @author xujie
 * @version 1.0
 * @date 2022/1/18 9:20
 */
@Data
@Accessors(chain = true)
public class Header {
    /**
     * 数据包头部长度(79 byte)
     */
    public static final byte HEADER_LENGTH = 79;
    /**
     * 业务ID(32 Byte)
     */
    private String bid;
    /**
     * 字符编码(1 Byte)
     */
    private CharsetEnum charset;
    /**
     * 消息是否加密(1 Byte)
     */
    private boolean encryption;
    /**
     * 指令: 9 Byte
     * 指令类型: 1 Byte
     * 指令分组: 4 Byte
     * 指令编码: 4 Byte
     */
    private Command command;
    /**
     * 消息签名(最大32 Byte)
     */
    private String signature;
    /**
     * 消息体长度(4 Byte)
     */
    private int bodyLength;

    public Header(String bid, CharsetEnum charset, boolean encryption, Command command, String signature) {
        this.bid = bid;
        this.charset = charset;
        this.encryption = encryption;
        this.command = command;
        this.signature = signature;
    }

    public Header(boolean encryption, Command command, String signature) {

        this.encryption = encryption;
        this.command = command;
        this.signature = signature;
    }

    public Header(Command command) {
        this.command = command;
    }

    public Header(String bid) {
        this.bid = bid;
    }

    public Header() {
    }

    public Header(String bid, CharsetEnum charset) {

        this.bid = bid;
        this.charset = charset;
    }

    /**
     * 获取业务ID字节数组,如果业务ID不足32字节则补足32字节,如果超过则截断
     *
     * @return
     */
    public byte[] getBidToArray() {
        byte[] bidArray = new byte[32];
        if (this.bid != null) {
            byte[] bytes = this.bid.getBytes(this.charset.getCharset());
            System.arraycopy(bytes, 0, bidArray, 0, bytes.length >= 32 ? 32 : bytes.length);
        }
        return bidArray;
    }

    /**
     * 获取消息签名字节数组,如果消息签名不足32个字节则补足32个字节,如果超过则截断
     *
     * @return
     */
    public byte[] getSignatureToArray() {
        byte[] signatureArray = new byte[32];
        if (this.signature != null) {
            byte[] bytes = this.signature.getBytes(this.charset.getCharset());
            System.arraycopy(bytes, 0, signatureArray, 0, bytes.length >= 32 ? 32 : bytes.length);
        }
        return signatureArray;
    }

    /**
     * 获取字符集对象
     *
     * @return
     */
    public Charset getCharset() {
        return charset != null ? charset.getCharset() : null;
    }

    /**
     * 获取字符集编码
     *
     * @return
     */
    public byte getCharsetCode() {
        return charset != null ? charset.getCode() : 0;
    }

    /**
     * 设置字符集
     *
     * @param charset
     */
    public void setCharset(Charset charset) {
        if (charset != null) {
            this.charset = CharsetEnum.valueOf(charset);
        }
    }

    /**
     * 设置字符集
     *
     * @param charsetCode
     */
    public void setCharset(byte charsetCode) {
        this.charset = CharsetEnum.valueOf(charsetCode);
    }
}
